// `include    "top_define.v"
//crc域计算
//10.08.25
//更改为哈希10
module hash(
            clk         ,
            rst_n       ,
            mac_dest    ,
            mac_sour    ,
            mac_addr_en ,
            hash_en     ,
            hash_dest   ,
            hash_sour       
            );
input        clk         ;
input        rst_n       ;
input [47:0] mac_dest    ;
input [47:0] mac_sour    ;
input        mac_addr_en ;
output       hash_en     ;

output[9:0] hash_dest ;
output[9:0] hash_sour ;


reg   [9:0]  crc_reg1 ;
reg   [9:0]  crc_reg2 ;

reg   [9:0]  hash_dest_reg10;
reg   [9:0]  hash_sour_reg10;
reg          hash_en;

assign hash_dest= hash_dest_reg10;
assign hash_sour= hash_sour_reg10;

/**************************************CRC48并行计算，数据位宽48***********************************************************************/
  // polynomial: (0 2 15 16)
  // data width: 48
  // convention: the first_n serial bit is D[15]

function [9:0] CRC48_D10;
    input [47:0] Data;
    input [9:0] crc ;
    reg [47:0] d     ;
    reg [ 9:0] c     ;
    reg [ 9:0] newcrc;
    begin
    d = Data;
    c = crc;
    newcrc[9]  = d[47]^d[46]^d[44]^d[43]^d[42]^d[41]^d[40]^d[38]^d[37]^d[34]^d[33]^d[29]^d[27]^d[26]^d[25]^d[19]^d[14]^d[13]^d[12]^d[11]^d[10]^d[0]^c[8]^c[6]^c[5]^c[1];
    newcrc[8]  = d[46]^d[45]^d[40]^d[39]^d[37]^d[35]^d[33]^d[30]^d[29]^d[28]^d[25]^d[20]^d[19]^d[15]^d[1]^c[9]^c[8]^c[7]^c[6]^c[4]^c[1]^c[0];
    newcrc[7]  = d[47]^d[46]^d[41]^d[40]^d[38]^d[36]^d[34]^d[31]^d[30]^d[29]^d[26]^d[21]^d[20]^d[16]^d[11]^d[2]^c[8]^c[7]^c[6]^c[5]^c[3]^c[0];
    newcrc[6]  = d[47]^d[42]^d[41]^d[39]^d[37]^d[35]^d[32]^d[31]^d[30]^d[27]^d[22]^d[21]^d[17]^d[12]^d[3]^c[9]^c[7]^c[6]^c[5]^c[4]^c[2];
    newcrc[5]  = d[47]^d[46]^d[44]^d[41]^d[37]^d[36]^d[34]^d[32]^d[31]^d[29]^d[28]^d[27]^d[26]^d[25]^d[23]^d[22]^d[19]^d[18]^d[14]^d[12]^d[11]^d[10]^d[4]^c[9]^c[4]^c[3]; 
    newcrc[4]  = d[46]^d[45]^d[44]^d[43]^d[41]^d[40]^d[35]^d[34]^d[32]^d[30]^d[28]^d[25]^d[24]^d[23]^d[20]^d[15]^d[14]^d[10]^d[5]^c[9]^c[6]^c[5]^c[3]^c[2]^c[1];
    newcrc[3]  = d[47]^d[46]^d[45]^d[44]^d[42]^d[41]^d[36]^d[35]^d[33]^d[31]^d[29]^d[26]^d[25]^d[24]^d[21]^d[16]^d[15]^d[11]^d[6]^c[8]^c[5]^c[4]^c[2]^c[1]^c[0];
    newcrc[2]  = d[47]^d[46]^d[45]^d[43]^d[42]^d[37]^d[36]^d[34]^d[32]^d[30]^d[27]^d[26]^d[25]^d[22]^d[17]^d[16]^d[12]^d[7]^c[9]^c[7]^c[4]^c[3]^c[1]^c[0];
    newcrc[1]  = d[47]^d[46]^d[44]^d[43]^d[38]^d[37]^d[35]^d[33]^d[31]^d[28]^d[27]^d[26]^d[23]^d[18]^d[17]^d[13]^d[8]^c[9]^c[8]^c[6]^c[3]^c[2]^c[0];
    newcrc[0]  = d[46]^d[45]^d[43]^d[42]^d[41]^d[40]^d[39]^d[37]^d[36]^d[33]^d[32]^d[28]^d[26]^d[25]^d[24]^d[18]^d[13]^d[12]^d[11]^d[10]^d[9]^c[9]^c[7]^c[6]^c[2];
    CRC48_D10 = newcrc;
    end
endfunction

always @(posedge clk or negedge rst_n)
    if(~rst_n)
    begin
        crc_reg1     <= 10'h3ff;
		crc_reg2     <= 10'h3ff;
	    hash_en 	 <= 1'b0;
	    hash_dest_reg10 <= 10'b0;
        hash_sour_reg10 <= 10'b0;
	end
	else if(mac_addr_en)
        begin
            hash_dest_reg10      <= CRC48_D10(mac_dest,crc_reg1);
			hash_sour_reg10      <= CRC48_D10(mac_sour,crc_reg2);    
            hash_en		         <= 1'b1; 
            crc_reg1             <= 10'h3ff;                    
            crc_reg2             <= 10'h3ff;                    
        end
    else
    begin
        crc_reg1     <= 10'h3ff;
		crc_reg2     <= 10'h3ff;
	    hash_en 	 <= 1'b0;
	    hash_dest_reg10 <= 10'b0;
        hash_sour_reg10 <= 10'b0;     
    end
	


endmodule
